Repository navigation
[SPARK-61157][CONNECT][PYTHON] Capture the call sites of the origins of Column operations without importing a missing IPython module on every call - #346
Closed
HyukjinKwon wants to merge 1 commit into
Conversation
…of Column operations without importing a missing IPython module on every call Each Column operation captured its call site with `_capture_call_site` of pyspark.errors.utils, which runs `import IPython` and `import ipykernel` on every call. Where ipykernel is not installed, each failing import scans sys.path again, so 90k Column operations took 7.3 s against 0.32 s with debugging off. The call site is now computed in origin.rs with the same result: the frames outside the pyspark package, and within an IPython shell without the frames of IPython and ipykernel, as "line N in cell [K]". IPython and ipykernel are read from sys.modules, and imported at most once per process. The vendored module is unchanged. Co-authored-by: Isaac <no-reply@databricks.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
SPARK-61157: Capture the call sites of the origins of Column operations without importing a missing IPython module on every call.
Every Column operation of the Python client calls
_with_origin, which in PySpark captures the call site of the user code withpyspark.errors.utils._capture_call_site. That function runsimport IPythonandimport ipykernelon every call. Where ipykernel is not installed, each failing import scanssys.pathagain.origin.rscaptures the call site in Rust, with the result of_capture_call_site(1): the frames outside the pyspark package, which are "file:line", and within an IPython shell, without the frames of IPython and ipykernel, "line N in cell [K]". The frames are joined by newlines, as before.sys.modules. When one of them is not loaded, the import is tried once per process and a failure is not retried; a module imported later by the user is still seen.pyspark/errors/utils.pyis unchanged, andis_debugging_enabledis unchanged.test_parity_dataframe_query_context.py) pass on the drop-in, 6 of 6.Why are the changes needed?
With ipykernel not installed, 90k Column operations (
F.col("a") + 1,* 2,.alias) took 6.8 s, against 0.23 s with debugging off.spark.range(1).select(*2000 names)five times took 0.66 s, against 0.004 s with debugging off. Official PySpark pays the same per-call cost in this helper (10.7 s for the same run on that machine); in the drop-in, whose own work per Column operation is small, nearly all of the time went to the failing imports.After this change, the same run takes 0.77 s with debugging on, and the select 0.022 s.
Does this PR introduce any user-facing change?
No. The error messages and the query contexts are the same. Column operations are faster when IPython or ipykernel is not installed.
How was this patch tested?
test_column_origins_capture_their_call_site_without_importing_per_call: 200 Column operations on the mock server import IPython and ipykernel at most once (the counting__import__sees 800 imports without this change), and the request of a Column built on the test line carries the string that_capture_call_site(1)gives on that line.test_parity_dataframe_query_context.pyon the drop-in against a live server: 6 passed, as before.wasm-udf, the offline Python suites (2202 passed, 8 skipped), and the live drop-in, Arrow and ML suites (184 passed) and live cases (10 passed). rustfmt passes, and clippy reports no diagnostics in the changed lines.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude Opus 5.5
This pull request and its description were written by Isaac.